perm filename DV.FIX[MF,ALS]5 blob sn#791327 filedate 1985-04-25 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00003 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002
C00021 00003	**
C00040 ENDMK
C⊗;


@<Constants...@>=
@!m1_max=4-1; {max size of first |mm_store| index}
@!m2_max=80000-1; {max size of second |mm_store| index}
@!mm_max=320000-1; {size of |mm_store|}


@d stow(#)==begin mm_store[m1,m2]←#;
    if mm=mm_e_cleared then make_space;
    if m2<m2_max then begin incr(m2); incr(mm); end
    else
	begin
	m2←8; {|-8<m2<8| freed for down-loading and |make_space| signs}
	mm←mm+8;
	if m1<m1_max then incr(m1) else begin m1←0; mm←8; end;
	end;
    end

@<Glob...@>=
@!mm_store:packed array [0..m1_max,0..m2_max] of eight_bits; {to store rasters}
@!mm_e_cleared:integer; {where cleared area in mm_store ends}
@!font_start:array [0..max_fonts] of integer; {font numbers at mm_starts}
@!m1,m2:integer; {indices for |mmm_store|}
@!data_start:array [0..max_fonts] of integer; {|data_base+bc| for fonts}
@!font_start:array [0..max_fonts] of integer; {font number at |data_start|}
@!data_end:array [0..max_fonts] of integer; {|data_base+ec| for fonts}
@!free_from:integer; {current start of space to be freed}
@!free_to:integer; {current end of space to be freed}

@ @<Set init...@>=
mm←8; m1←0; m2←8; {|-8<mm<8| saved for signalling purposes}
mm_e_cleared←mm_max;
for i←0 to max_fonts do
	begin
	font_starts[i]←-1; font_numbers[i]←-1;
        data_start←-1; font_start[i]←-1;
	end;

----------
SAVE m1 AMD m2 at start of stow all of the glyph-raster
do this in m1_save and m2_save for temporary use.
Also save mm and cur_font in data_start and font_start for the start of the
entire font.

----------

mm_save,m1_save,m2_save:integer; {temp hold of starting location for each glyph}

TO ADD TO THE FONT LOADING TRAIL
i←0; 
while data_ptr[i]>0 do incr(i); 
data_start[cur_font]←width_ptr; {Index to start of |width|s}
data_ptr[i]←mm; {index to |mm_store| where glyph data is stored}
font_order[i]←cur_font;


@p procedure free_space;
	 {zero affected |m_store| area and + valued |glyph_ptr|'s}
var i,j: integer;
begin
j←cur_font mod m_m_num; {defining section of |m_store| to be cleared}
for i←0 to max_glyphs do
  if (glyph_ptr[i]div m_store_size) = j then
    if glyph_ptr[i] >0 then glyph_ptr[i]←0; {marking glyphs as removed}
for i←0 to m_store_size do m_store[j,i]←0; {marking space as available}
s_i[j]←0; {preparing to start at the beginning}
end;

@p procedure make_space; 
var j,k,q,q1,q2: integer;
begin
j←data_start[font_order[0]];
k←data_start[font_order[1]];
q←glyph_ptr[k];
q1←q div q2_size; q2←q mod q2_size;
if q2>4 then free_limit←q-1 else
    begin q2←q2_max; if q1>0 then q1←q1-1 else q1←q1_max;
    free_limit←q1*q2_size+q2;
    end;
for i←j to k-1 do 
    if glyph_ptr[i]≥4 then glyph_ptr[i]←0; {mark as no longer available}
for i←0 to max_fonts-1 do font_order[i]←font_order[i+1];
end;

********

@ @<Stow all...@>=
repeat gf_prev_ptr←cur_gf_loc;
@<Pass |no_op|, |xxx| and |yyy| commands@>;
if (o=boc) or (o=boc1) then
  begin
  mm_sav←mm; m1_save←m1; m2_save←m2; {for possible width and height corrections}
  if o=boc then  begin @<Stow the |boc| information@> end
  else begin @<Stow the |boc1| information@>;
  end;
if empty_glyph then
    begin
    glyph_ptr[data_base[cur_font]+c]←-1;
    empty_glyph←false;
    end
else
glyph_ptr[data_base[cur_font]+c]←
	m1*(m2_max+1)+m2;
	{save mask start address}

{|print(' (',c:1,')',s_i[cur_font mod m_m_num]:1);|}
@!debug
print(' (',cur_font:1,')',c:1,'[',m1:1,',',m2:1,']');
gubed@/
  @<Stow the glyph details@>;
  end;
until o=post;

@ @<Stow the |boc| information@>=
incr(total_glyphs);
char_code←gf_signed_quad;
p←gf_signed_quad;
c←char_code mod 256;
if c<0 then c←c+256;
if c>127 then if im_extension[cur_font]=-1 then
    begin
    if nf2=nf then
	begin
	print_ln(' ---Out of font storage space');
	goto 9998;
	end;
    im_extension[cur_font]←nf2; decr(nf2);
    end;
@!debug
print(' boc[',c:1,']');
if char_code≠c then
	print(' in family ',(char_code-c) div 256 : 1);
gubed@/
min_m←gf_signed_quad; max_m←gf_signed_quad;
min_n←gf_signed_quad; max_n←gf_signed_quad;
if max_m-min_m≤0 then empty_glyph←true else empty_glyph←false;
stow_signed_pair(max_m-min_m+1); {width}
stow_signed_pair(-min_m); {left offset}
				height_location←s_i[cur_font mod m_m_num];
stow_signed_pair(max_n-min_n+1); {height}
stow_signed_pair(max_n); {top offset}

@ @<Stow the |boc1| information@>=
{|print(' at boc1 ');|}
incr(total_glyphs);
char_code←gf_byte;
p←-1;
c←char_code;
if c>127 then if im_extension[cur_font]=-1 then
    begin
    if nf2=nf then
	begin
	print_ln(' ---Out of font storage space');
	goto 9998;
	end;
    im_extension[cur_font]←nf2; decr(nf2);
    end;
@!debug
print_ln(''); print_ln('');
print(' boc1[',c:1,']');
gubed@/
del_m←gf_byte; max_m←gf_byte;
del_n←gf_byte; max_n←gf_byte;
if del_m≤0 then empty_glyph←true else empty_glyph←false;
stow_signed_pair(del_m+1);
stow_signed_pair(del_m-max_m);
stow_signed_pair(del_n+1);
stow_signed_pair(max_n);
@!debug
print_ln(' c=',c:1,' del_m+1=',del_m+1:1,' del_m-max_m=',del_m-max_m:1,
' del_n+1=',del_n+1:1,' max_n=',max_n:1);
gubed@/


mm_store[m1_save,m2_save]←max_column_count div 256;
if m2_save<m2_max then incr(m2_save) else
    begin m2_save←8; if m1_save<m1_max then incr(m1_save)
        else m1_save←0;
    end;
mm_store[m1_save,m2_save]←max_column_count mod 256;
if m2_save+3<m2_max then m2_save←m2_save+3 else
    begin m2_save←m2_save+11-m2_max; if m1_save<m1_max then incr(m1_save)
	else m1_save←0;
    end
mm_store[m1_save,m2_save]←row_count div 256;
if m2_save<m2_max then incr(m2_save) else
    begin m2_save←8; if m1_save<m1_max then incr(m1_save)
        else m1_save←0;
    end;
mm_store[(m1_save,m2_save]←row_count mod 256;

@ When it becomes necessary to remove an already stored font to make room
for a new font, we get the number of the font to be removed from the
|font_start| array and locate the |mm_store| data to be removed by getting
its starting location and ending location from the |data_start| array.
We also zero all relevant positive, >7,
 pointers (pointing to glyphs that have not
been downloaded) in the |glyph_ptr| array. We can them
locate the next |mm| value where the next byte is to be stored and define
a new value for |mm_e|cleared|.  Finally, we shift all |data_start| and
|font_start| entries down one in preparation for still another |free_space|
operation should this become necessary.

@p procedure free_space;
	 {zero affected |mm_store| area and + valued |glyph_ptr|'s}
var i,j,k,l: integer;
q1,q2: integer;
begin
j←data_start[0];
k←data_start[1];
l←font_start[0];
for i←data_starts[l] to data_ends[l] do
	if glyph_ptr[i]>3 then glyph_ptr[1]←0;
q1←j div (m2_max+1); q2←j mod (m2_max+1);
if k>j then {the glyph records to be removed do not wrap around}
    begin
    for i←j to k-1 do 
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←4; incr(q1);
	    end;
	end;
    end
else
    begin {a wrap_around condition exists}
    for i←j to mm_max do
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←4; incr(q1);
	    end;
	end;
    q1←0; q2←4;
    for i←0 to k-1 do
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←4; incr(q1);
	    end;
	end;
mm←j;  { the location where the next byte goes}
mm_e_cleared←k-1; {the new last available |mm_store| location.
for i←0 to max_fonts-1 do
	begin
	data_start[i]←data_start[i+1];
	font_start[i]←font_start[i+1];
	end;


FOR INSERTION IN MODULE 56
	    @ @<Convert and store the width values@>=
	    @<Replace |z| by $|z|↑\prime$ and compute $\alpha,\beta$@>;
	    data_base[cur_font]←width_ptr-bc;
	    wp←width_ptr+ec-bc+1;
data_start[cur_font]←width_ptr;
data_end[cur_font]←wp-1;

@p function read_byte(z:integer):integer; {get the next byte from |mm_store|}
var b:eight_bits;
z1,z2:integer;
begin
z1←z div (m2_size); z2←z mod (m2_size);
read_byte←mm_store[z1,z2];
end;

@p function read_signed_pair(z:integer):integer;
	 {returns the next two bytes, signed}
var a,b:eight_bits;
z1,z2:integer;
begin 
z1←z div (m2_size); z2←z mod (m2_size);
a←mm_store[z1,z2];
if z2<z2_max then incr(z2)
else
    begin z2←4; 
    if z1<z1_max then incr(z1) else z1←0; {wrap-around assumed}
    end;
b←mm_store(z1,z2];
if a<128 then read_signed_pair←(a*256)+b
else read_signed_pair←(a-256)*256+b;
end;

@d advance_q==begin if q2<m2_max then incr(q2)
    else 
	begin
	q2←4; {|-4<m2<4| is left free for other uses}
 	if q1<m1_max then incr(q1) else q1←0;
	end;

@p procedure do_im_bgly(@!c:integer);
var b,dis,n,i,q,val,w,real_w:integer;
bytes_required:integer; {bytes per row for current glyph}
begin
im_byte(im_bgly);				{|im_bgly|}
if c<128 then im_halfword(cur_font*128+c) {normal family and member name}
else im_halfword(im_extension[cur_font]*128+c-128);
	{Imagen's family and member name}
q←pixel_width[data_base[cur_font]+c];
im_halfword(q); 				{advance width}
q←glyph_ptr[data_base[cur_font]+c];
	 {|glyph_ptr| points to mask start}
q1← q div (m2_size); q2←q mod (m2_size);
for 1←1 to 8 do
    begin
    im_byte(mm_store[q1,q2];
    advance_q;
    end; 	 {width, left offset, height,top offset}
n←0; dis←0; val←0; w←0; real_w←0;
while real_w≠eoc do begin
	@<Translate a sequence of paint commands@>;
	w←mm_store[q1,q2];
	real_w←w;
	if (w≥new_row_0) and (w≤new_row_164) then
		@<Translate a |new_row| command@>
	else if (w≥skip0) and (w<new_row_0) then
		@<Translate a |skip| command@>
else if real_w<>eoc then print_ln('STRANGE COMMAND ',w:1);
	end;
{|print_ln('G EOC');|}
glyph_ptr[data_base[cur_font]+c]←-glyph_ptr[data_base[cur_font]+c];
         {to show that the glyph has been downloaded}
end;

********

@ @<Get two paint commands@>=
begin w←mm_store[q1,2q];
if w≤paint2 then
    begin
    if w=paint2 then
	begin advance_q; w←mm_store[q1,q2]; advance_q;
	w←w*256+mm_store[q1,q2]; {can be as high as 65535}
	end
    else if w=paint1 then
	begin advance_q; w←mm_store[q1,q2]; {can be between 64 and 255}
	end;
    advance_q;
    b←mm_store[q1,q2];
    if b≤paint2 then
	begin
	if b=paint2 then
	    begin advance_q; b←mm_store[q1,q2]; advance_q;
	    b←b*256+mm_store[q1,q2];
	    end
	else if b=paint1 then
	    begin advance_q;
	    b←mm_store[q1,q2];
	    end;
	advance_q;
	end
      else
	begin
	b←0; w←8*bytes_required; {a safety measure}
	end;
    end
else
    begin b←0; w←8*bytes_required; {a safety measure}
    end;
end

@ @<Translate a |new_row| command@>=
begin
w←w-new_row_0;
advance_q;
b←mm_store[q1,q2];
if b≤paint2 then begin
	advance_q;
	if b=paint2 then
		begin b←mm_store[q1,q2]; advance_q;
		b←b*256+mm_store[q1,q2]; advance_q;
		end
	else if b=paint1 then begin
		b←mm_store[q1,q2]; advance_q;
		end;
	n←0; dis←w+b; val←0;
	end
else begin b←0; w←8*bytes_required; {a safety measure}
     end;
n←0; dis←w+b; val←0;
end


@ @<Translate a |skip| command@>=
begin
if w>skip0 then begin
	advance_q;
	w←mm_store[q1,q2];
	while w>0 do begin
		for n←1 to bytes_required do im_byte(0);
		decr(w);
		end;
	end;
advance_q;
n←0; dis←0; val←0; w←0; b←0;
end

---------------
**
@<Constants...@>=
@!m1_max=3; {max first |mm_store| index}
@!m2_size=60000; {used as multiplier or divider}
@!m2_max=m2_size-1; {max second |mm_store| index}
@!mm_size=240000; {bytes in |mm_store|}
@!mm_max=mm_size-1; {max location in |mm_store|}

@d stow(#)==begin mm_store[m1,m2]←#;
    if mm=free_limit then make_space;
    if m2<m2_max then begin incr(m2); incr(mm); end
    else
	begin
	m2←4; {|-4<m2<4| freed for down-loading and |make_space| signs}
	mm←mm+4;
	if m1<m1_max then incr(m1) else begin m1←0; mm←4; end;
	end;
    end
*******

@<Glob...@>=
@!mm_store:packed array [0..m1_max,0..m2_max] of eight_bits; {to store rasters}
@!m1,m2:integer; {indices for |mm_store|}
@!free_limit:integer; {|mm| value of last free location in mm_store}
@!data_start:array [0..max_fonts] of integer; {|data_base+bc| for fonts}
@!font_order:array [0..max_fonts] of integer; {font numbers in loaded order}
@!free_from:integer; {current start of space to be freed}
@!free_to:integer; {current end of space to be freed}

@ @<Set init...@>=
mm←4; m1←0; m2←4; {|-4<mm<4| saved for signalling purposes}
free_limit←mm_max;
for i←0 to max_fonts do
    begin font_start[i]←-1; data_start←-1; end;
**********
----------
SAVE m1 AMD m2 at start of stow all of the glyph-raster
do this in m1_save and m2_save for temporary use.
Also save mm and cur_font in data_start and font_start for the start of the
entire font.

----------
data_start[cur_font]←width_ptr; {Index to start of |width|s}

mm_save,m1_save,m2_save:integer; {temp save to allow for corrections}

i←0; while font_order[i]≥0 do incr(i);
font_order[i]←cur_font;

 
@ The parameter {free_limit| is set initially to |mm_max|. The following
procedure is used when it becomes necessary to make the oldest font as read
in no longer available so that its space in |mm_store| can be reused.

@p procedure make_space; 
var j,k,q,q1,q2: integer;
begin
j←data_start[font_order[0]];
k←data_start[font_order[1]];
q←glyph_ptr[k];
q1←q div q2_size; q2←q mod q2_size;
if q2>4 then free_limit←q-1 else
    begin q2←q2_max; if q1>0 then q1←q1-1 else q1←q1_max;
    free_limit←q1*q2_size+q2;
    end;
for 1←j to k-1 do 
    if glyph_ptr[i]≥4 then glyph_ptr[i]←0; {mark as no longer available}
for i←0 to max_fonts-1 do font_order[i]=font_order[i+1];
end;

@ @<Stow all...@>=
repeat gf_prev_ptr←cur_gf_loc;
@<Pass |no_op|, |xxx| and |yyy| commands@>;
if (o=boc) or (o=boc1) then
  begin
  m1_save←m1; m2_save←m2; {for possible width and height corrections}
  glyph_ptr[data_base[cur_font]+c]←m1*m2_size+m2; {save glyph start address}
print(' (',cur_font:1,')',c:1,'[',m1:1,',',m2:1,']');
@!debug
gubed@/
  if o=boc then  begin @<Stow the |boc| information@> end
  else begin @<Stow the |boc1| information@>;
  end;
if empty_glyph then
    begin {indicate this by overwriting the |glyph_ptr|}
    glyph_ptr[data_base[cur_font]+c]←-1; empty_glyph←false;
    end;
  @<Stow the glyph details@>;
  end;
until o=post;

@ @<Stow the |boc| information@>=
incr(total_glyphs);
char_code←gf_signed_quad;
p←gf_signed_quad;
c←char_code mod 256;
if c<0 then c←c+256;
if c>127 then if im_extension[cur_font]=-1 then
    begin
    if nf2=nf then
	begin
	print_ln(' ---Out of font storage space');
	goto 9998;
	end;
    im_extension[cur_font]←nf2; decr(nf2);
    end;
@!debug
print(' boc[',c:1,']');
if char_code≠c then
	print(' in family ',(char_code-c) div 256 : 1);
gubed@/
min_m←gf_signed_quad; max_m←gf_signed_quad;
min_n←gf_signed_quad; max_n←gf_signed_quad;
if max_m-min_m≤0 then empty_glyph←true else empty_glyph←false;
stow_signed_pair(max_m-min_m+1); {width}
stow_signed_pair(-min_m); {left offset}
				height_location←s_i[cur_font mod m_m_num];
stow_signed_pair(max_n-min_n+1); {height}
stow_signed_pair(max_n); {top offset}

@ @<Stow the |boc1| information@>=
{|print(' at boc1 ');|}
incr(total_glyphs);
char_code←gf_byte;
p←-1;
c←char_code;
if c>127 then if im_extension[cur_font]=-1 then
    begin
    if nf2=nf then
	begin
	print_ln(' ---Out of font storage space');
	goto 9998;
	end;
    im_extension[cur_font]←nf2; decr(nf2);
    end;
@!debug
print_ln(''); print_ln('');
print(' boc1[',c:1,']');
gubed@/
del_m←gf_byte; max_m←gf_byte;
del_n←gf_byte; max_n←gf_byte;
if del_m≤0 then empty_glyph←true else empty_glyph←false;
stow_signed_pair(del_m+1);
stow_signed_pair(del_m-max_m);
			height_location←s_i[cur_font mod m_m_num];
stow_signed_pair(del_n+1);
stow_signed_pair(max_n);
@!debug
print_ln(' c=',c:1,' del_m+1=',del_m+1:1,' del_m-max_m=',del_m-max_m:1,
' del_n+1=',del_n+1:1,' max_n=',max_n:1);
gubed@/



mm_store[m1_save,m2_save]←row_count div 256;
if m2_save<m2_max then incr(m2_save) else
    begin m2_save←4; if m1_save<m1_max then incr(m1_save)
        else m1_save←0;
    end;
mm_store[(m1_save,m2_save]←row_count mod 256;
if m2_save+3<m2_max then m2_save←m2_save+3 else
    begin m2_save←m2_save+11-m2_max; if m1_save<m1_max then incr(m1_save)
	else m1_save←0;
    end
mm_store[m1_save,m2_save]←max_column_count div 256;
if m2_save<m2_max then incr(m2_save) else
    begin m2_save←4; if m1_save<m1_max then incr(m1_save)
        else m1_save←0;
    end;
mm_store[m1_save,m2_save]←max_column_count mod 256;

@ When it becomes necessary to remove an already stored font to make room
for a new font, we get the number of the font to be removed from the
|font_start| array and locate the |mm_store| data to be removed by getting
its starting location and ending location from the |data_start| array.
We also zero all relevant positive, >7,
 pointers (pointing to glyphs that have not
been downloaded) in the |glyph_ptr| array. We can them
locate the next |mm| value where the next byte is to be stored and define
a new value for |mm_e|cleared|.  Finally, we shift all |data_start| and
|font_start| entries down one in preparation for still another |free_space|
operation should this become necessary.

@p procedure free_space;
	 {zero affected |mm_store| area and + valued |glyph_ptr|'s}
var i,j,k,l: integer;
q1,q2: integer;
begin
j←data_start[0];
k←data_start[1];
l←font_start[0];
for i←data_starts[l] to data_ends[l] do
	if glyph_ptr[i]>7 then glyph_ptr[1]←0;
q1←j div (m2_size); q2←j mod (m2_size);
if k>j then {the glyph records to be removed do not wrap around}
    begin
    for i←j to k-1 do 
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←0; incr(q1);
	    end;
	end;
    end
else
    begin {a wrap_around condition exists}
    for i←j to mm_max do
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←0; incr(q1);
	    end;
	end;
    q1←0; q2←0;
    for i←0 to k-1 do
	begin
	mm_store[q1,q2]←0;
	if q2<m2_max then incr(q2)
	else begin
	    q2←0; incr(q1);
	    end;
	end;
mm←j;  { the location where the next byte goes}
free_limit←k-1; {the new last available |mm_store| location.
for i←0 to max_fonts-1 do
	begin
	data_start[i]←data_start[i+1];
	font_start[i]←font_start[i+1];
	end;


FOR INSERTION IN MODULE 56
	    @ @<Convert and store the width values@>=
	    @<Replace |z| by $|z|↑\prime$ and compute $\alpha,\beta$@>;
	    data_base[cur_font]←width_ptr-bc;
	    wp←width_ptr+ec-bc+1;
data_start[cur_font]←width_ptr;
data_end[cur_font]←wp-1;

@d advance_q==begin if q2<m2_max then incr(q2)
   else begin q2←4; if q1<m1_max then incr(q1) else q1←0end;

@p procedure do_im_bgly(@!c:integer);
var b,dis,n,i,q,val,w,real_w:integer;
bytes_required:integer; {bytes per row for current glyph}
begin
im_byte(im_bgly);				{|im_bgly|}
if c<128 then im_halfword(cur_font*128+c) {normal family and member name}
else im_halfword(im_extension[cur_font]*128+c-128);
	{Imagen's family and member name}
q←pixel_width[data_base[cur_font]+c];
im_halfword(q); 				{advance width}
q←glyph_ptr[data_base[cur_font]+c];
	 {|glyph_ptr| points to mask start}
q1← q div (m2_size); q2←q mod (m2_size);
q1_save←qi; q2_save←q2
b←mm_store[q1,q2]; advance_q; b←b*256+mm_store[q1,q2];
bytes_required←(b+7)div 8;
q1←q1_save; q2←q2_save;
for i←1 to 8 do
    begin {download width, left offset, height, and top offset}
    im_byte(mm_store[(q1,q2]; advance_q;
    end;
n←0; dis←0; val←0; w←0; real_w←0;
while real_w≠eoc do begin
	@<Translate a sequence of paint commands@>;
	w←mm_store[q1,q2];
	real_w←w;
	if (w≥new_row_0) and (w≤new_row_164) then
		@<Translate a |new_row| command@>
	else if (w≥skip0) and (w<new_row_0) then
		@<Translate a |skip| command@>
else if real_w<>eoc then print_ln('STRANGE COMMAND ',w:1);
	end;
{|print_ln('G EOC');|}
glyph_ptr[data_base[cur_font]+c]←-glyph_ptr[data_base[cur_font]+c];
         {to show that the glyph has been downloaded}
end;



@ @<Get two paint commands@>=
begin
w←mm_store[q1,2q];
if w≤paint2 then
    begin
    if w=paint2 then
	begin advance_q; w←mm_store[q1,q2]; advance_q;
	w←w*256+mm_store[q1,q2]; {this can be a value as high as 65535}
	end
    else if w=paint1 then
	begin advance_q;
	w←mm_store[q1,q2]; {this can be between 64 and 255}
	end
    else begin
	end;
    advance_q;
    b←mm_store[q1,q2];
    if b≤paint2 then
	begin
	if b=paint2 then
	    begin advance_q; b←mm_store[q1,q2]; advance_q;
	    b←b*256+mm_store[q1,q2]; {this can be a value as high as 65535}
	    end
	else if b=paint1 then
	    begin advance_q;
	    b←mm_store[q1,q2]; {this can be between 64 and 255}
	    end
	else begin
	    end;
	advance_q;
	end
      else
	begin
	b←0; w←8*bytes_required; {a safety measure}
	end;
    end
else
    begin
    b←0; w←8*bytes_required; {a safety measure}
    end;
end



@ @<Translate a |new_row| command@>=
begin
w←w-new_row_0;
advance_q;
b←mm_store[q1,q2];
if b≤paint2 then begin
	advance_q;
	if b=paint2 then
		begin b←mm_store[q1,q2]; advance_q;
		b←b*256+mm_store[q1,q2]; {this can be a value as high as 65535}
		advance_q;
		end
	else if b=paint1 then begin
		b←mm_store[q1,q2]; advance_q;
		end;
	n←0; dis←w+b; val←0;
	end
else begin
	b←0; w←8*bytes_required; {a safety measure}
	end;
n←0; dis←w+b; val←0;
end


@ @<Translate a |skip| command@>=
begin
if w>skip0 then begin
	advance_q;
	w←mm_store[q1,q2];
	while w>0 do begin
		for n←1 to bytes_required do im_byte(0);
		decr(w);
		end;
	end;
advance_q;
n←0; dis←0; val←0; w←0; b←0;
end

---------------